home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
think
/
AmigaGnuChess.lha
/
chess
/
src.lha
/
src
/
amiga
/
amiterm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-09-06
|
13KB
|
664 lines
/*
* Amiga curses-style terminal routines.
* Taken from Amiga ISpell, and hacked to fit GNUCHESS.
*
* (C) 1992 Martin W. Scott.
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <libraries/gadtools.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/gadtools.h>
#include <proto/intuition.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdarg.h>
#include <ctype.h>
#include "display.h"
#include "amiterm.h"
#include "draw.h"
#include "pointer.h"
#include "requester.h"
#include "gnuchess.h" /* for struct flag definition */
/* Prototypes for static functions */
static void CloseLibs(void);
static BOOL OpenLibs(void);
static BOOL Open_Console(struct IOStdReq *rq, struct Window *win);
static void CleanUp(void);
static void putcon(struct IOStdReq *rq, char *str);
static void __stdargs printc(char *fmt, ...);
static void cursor_off(void);
static void cursor_on(void);
static void con_set_line(int offset, int len);
static void con_set_pagelen(void);
static void setcolors(int color);
static void DisableWindow(void);
static void EnableWindow(void);
static void About(void);
static int mousebutton(BOOL down, WORD x, WORD y);
static int menupick(WORD menu, WORD item, WORD subitem);
static int getevent(struct Window *ApplWin);
/* special event 'char's */
#define IGNORE_EVENT -1
#define MOUSE_MOVE 1000
#define MENU_PICK 1001
/* libraries */
struct IntuitionBase *IntuitionBase;
struct GadToolsBase *GadToolsBase;
struct GfxBase *GfxBase;
struct Library *ReqToolsBase;
/* storage */
static char movestr[6]; /* mousebutton move */
static char *menuchoice; /* menu => command */
struct RastPort *rp;
static struct IOStdReq *scr_rq = NULL;
static int get_file; /* next string from filereq */
static char *frhail; /* hail-text for filereq */
int get_command; /* use mouse/menus for input */
static char colorfile[100]; /* name of color file */
/* close libraries that were opened */
static void
CloseLibs()
{
if (ReqToolsBase) CloseLibrary(ReqToolsBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (GfxBase) CloseLibrary(GfxBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
}
/* open required libraries */
static BOOL
OpenLibs()
{
if ((IntuitionBase = (void *)OpenLibrary("intuition.library",37L)) &&
(GfxBase = OpenLibrary("graphics.library", 37L)) &&
(GadToolsBase = (void *)OpenLibrary("gadtools.library",37L)))
{
ReqToolsBase = (void *)OpenLibrary("reqtools.library", 37L);
return TRUE;
}
CloseLibs();
return FALSE;
}
static BOOL
Open_Console(struct IOStdReq *rq, struct Window *win)
{
rq->io_Data = (APTR) win;
rq->io_Length = sizeof(struct IOStdReq);
if (OpenDevice("console.device",0,rq,0))
return(FALSE); /* could not get device */
return(TRUE); /* device opened successfully */
}
static void
CleanUp()
{
if (scr_rq)
{
if (scr_rq->io_Device) CloseDevice(scr_rq);
FreeMem(scr_rq, sizeof(struct IOStdReq));
scr_rq = NULL;
}
CloseChessWindow();
CloseDownScreen();
CloseLibs();
}
void
endwin()
{
CleanUp();
}
int
initscr()
{
if (!OpenLibs())
return FALSE;
if (!(scr_rq = AllocMem(sizeof(struct IOStdReq), MEMF_PUBLIC | MEMF_CLEAR)))
{
CloseLibs();
return FALSE;
}
strcpy(colorfile, libdir);
AddPart(colorfile, "gnuchess.colors", sizeof(colorfile));
LoadColors(colorfile); /* may fail...who cares? */
if ((SetupScreen() == 0) &&
(OpenChessWindow() == 0) &&
(Open_Console(scr_rq, ChessWnd)))
{
rp = ChessWnd->RPort;
return TRUE;
}
CleanUp();
return FALSE;
} /* initscr */
/********************************************************************************/
/* Buffered output routines */
/********************************************************************************/
#define CONBUFSIZ 128
static char putbuf[CONBUFSIZ+1];
static UWORD bufpos;
#define putch(ch) {if (bufpos == CONBUFSIZ) refresh(); putbuf[bufpos++] = (ch);}
#define inst_putch(ch) putch(ch); refresh()
void
refresh()
{
putbuf[bufpos]='\0';
putcon(scr_rq, putbuf);
bufpos=0;
chkabort();
}
void
putstr(char *str)
{
if (strlen(str) >= (CONBUFSIZ-bufpos))
refresh();
while (*str)
putch(*str++);
}
/*******************************************************************************/
static void
putcon(struct IOStdReq *rq, char *str)
{
/* in case the console has not been initialized */
if ( rq == NULL ) {
fprintf(stdout,"%s",str);
return;
}
rq->io_Command = CMD_WRITE;
rq->io_Data = (APTR) str;
rq->io_Length = -1;
DoIO(rq);
}
static void __stdargs
printc(char *fmt, ...)
{
va_list ap;
char pbuff[256];
va_start(ap,fmt);
vsprintf(pbuff,fmt,ap);
putstr(pbuff);
}
static void
cursor_off()
{
printc("%c%c%c%c",0x9b,0x30,0x20,0x70);
}
static void
cursor_on()
{
printc("%c%c%c",0x9b,0x20,0x70);
}
static void
con_set_line(int offset,int len)
{
char buf[10];
sprintf(buf,"%d",(short)offset);
printc("%c%s%c",0x9b,buf,0x78);
sprintf(buf,"%d",(short)len);
printc("%c%s%c",0x9b,buf,0x75);
}
static void
con_set_pagelen()
{
printc("%c%c",0x9b,0x74);
}
static void
setcolors(int color)
{
char buf[100];
sprintf(buf,"\x9b%dm", color);
putstr(buf);
}
static void
EnableWindow()
{
struct MenuItem *item;
ModifyIDCMP(ChessWnd, CHESS_IDCMP);
/* update menu toggle status */
item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, REVERSE, 0));
if (flag.reverse) item->Flags |= CHECKED;
else item->Flags &= ~CHECKED;
item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, COORDINATES, 0));
if (flag.coords) item->Flags |= CHECKED;
else item->Flags &= ~CHECKED;
item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, THINKING, 0));
if (flag.post) item->Flags |= CHECKED;
else item->Flags &= ~CHECKED;
item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, RANDOM, 0));
if (dither) item->Flags |= CHECKED;
else item->Flags &= ~CHECKED;
item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, BEEP, 0));
if (flag.beep) item->Flags |= CHECKED;
else item->Flags &= ~CHECKED;
/***
item = ItemAddress(ChessMenus, FULLMENUNUM(TOGGLES, USEBOOK, 0));
if (Book) item->Flags |= CHECKED;
else item->Flags &= ~CHECKED;
NOT WORKING... ***/
SetMenuStrip(ChessWnd, ChessMenus);
}
static void
DisableWindow() /* let user type ahead, but no more */
{
ClearMenuStrip(ChessWnd);
ModifyIDCMP(ChessWnd, IDCMP_VANILLAKEY);
}
#define ABOUT_TXT_1 "\
Welcome to Amiga GnuChess Version 1.0,\n\
derived from GNU Chess Version 4.00, patchlevel 58.\n\
\n\
GNU Chess is Copyright (c) 1986-1992 Free Software Foundation.\n\
Amiga graphics display is Copyright (c) 1992 Martin W. Scott.\n\
Freely redistributable, subject to the GNU General Public Licence.\n\
"
#define ABOUT_TXT_2 "\
You may contact the author of this Amiga port at:\n\
\n\
Martin W. Scott,\n\
23, Drum Brae North,\n\
Edinburgh, EH4 8AT\n\
United Kingdom.\n\
\n\
This version was released in September of 1992.\n\
Thanks to Nico François for reqtools.library.\
"
/* EasyEasyrequest... */
static void
About()
{
struct EasyStruct es;
char *arglist[2];
es.es_StructSize = sizeof(struct EasyStruct);
es.es_Flags = 0L;
es.es_Title = "About Amiga GnuChess";
es.es_TextFormat = "%s%s";
es.es_GadgetFormat = "OK";
arglist[0] = ABOUT_TXT_1;
arglist[1] = ABOUT_TXT_2;
EasyRequestArgs(ChessWnd, &es, NULL, arglist);
}
/* convert mouse-event to chess-square string */
/* to do?: erase square and make pointer an image of the piece 'held' */
static int
mousebutton(BOOL down, WORD x, WORD y)
{
static UWORD from_row, from_col;
static BOOL have_from;
UWORD row, col;
int rv = -1;
row = 7-(y-TOP_OFFSET)/SQUARE_HEIGHT;
col = (x-LEFT_OFFSET)/SQUARE_WIDTH;
if (!have_from && down) /* from square selected */
{
if (row < 8 && col < 8)
{
AmiToggleSquare(row,col);
from_row = row;
from_col = col;
have_from = TRUE;
SetToPointer(ChessWnd);
}
/* else ignore mouse-command */
}
else if (have_from) /* to square selected */
{
ClrToPointer(ChessWnd);
AmiToggleSquare(from_row,from_col); /* restore from-square */
if ((row < 8 && col < 8) && /* in bounds */
(from_row != row || from_col != col)) /* aborted */
{
if (flag.reverse) /* convert position */
{
from_row = 7-from_row;
from_col = 7-from_col;
row = 7-row;
col = 7-col;
}
sprintf(movestr, "%c%c%c%c", from_col+'a', from_row+'1',
col+'a', row+'1');
rv = MOUSE_MOVE;
}
have_from = FALSE;
}
return rv;
}
/* convert menu choice to command strings */
static int
menupick(WORD menu, WORD item, WORD subitem)
{
int rv = MENU_PICK;
switch (menu)
{
case PROJECT:
switch (item)
{
case NEW_GAME: menuchoice = "new"; break;
case LOAD_GAME: menuchoice = "get";
frhail = "Load game...";
get_file = TRUE;
break;
case SAVE_GAME: menuchoice = "save";
frhail = "Save game...";
get_file = TRUE;
break;
case LISTING: menuchoice = "list"; break;
case EDITBOARD: menuchoice = "edit"; break;
case SHOWHELP: menuchoice = "help"; break;
case QUIT: menuchoice = "quit"; break;
case ABOUT: About();
default: rv = -1;
}
break;
case SETTINGS:
switch (item)
{
case SET_CLOCK: menuchoice = "clock"; break;
case COLORS: DoPalette(ChessWnd); rv = -1; break;
case SAVECOLORS: SaveColors(colorfile);
default: rv = -1;
}
break;
case TOGGLES:
switch (item)
{
case REVERSE: menuchoice = "reverse"; break;
case COORDINATES: menuchoice = "coords"; break;
case THINKING: menuchoice = "post"; break;
case RANDOM: menuchoice = "random"; break;
case BEEP: menuchoice = "beep"; break;
/* case USEBOOK: menuchoice = "book"; break;*/
default: rv = -1;
}
break;
case MOVE:
switch (item)
{
case GO: menuchoice = "go"; break;
case UNDO: menuchoice = "undo"; break;
case REMOVE: menuchoice = "remove"; break;
case SWITCH: menuchoice = "switch"; break;
case FORCE: menuchoice = "force"; break;
case REDRAW: menuchoice = "bd"; break;
case HINT: menuchoice = "hint"; break;
default: rv = -1;
}
break;
default: rv = -1;
}
return rv;
}
/* get input from user and tokenize it */
static int
getevent(struct Window *ApplWin)
{
struct IntuiMessage *mess;
int retval = IGNORE_EVENT;
/* wait for an intuition event */
while( !(mess = (struct IntuiMessage *)GetMsg(ApplWin->UserPort)) )
Wait(1 << ApplWin->UserPort->mp_SigBit);
switch(mess->Class) {
case IDCMP_VANILLAKEY:
retval = mess->Code;
if (isprint(retval))
inst_putch(retval);
break;
case IDCMP_MENUPICK:
retval = menupick(MENUNUM(mess->Code), ITEMNUM(mess->Code), SUBNUM(mess->Code));
break;
case IDCMP_MOUSEBUTTONS:
retval = mousebutton(mess->Code == SELECTDOWN, mess->MouseX, mess->MouseY);
break;
default:
break;
}
ReplyMsg(mess);
return(retval);
}
/*
* end of amiga console support.
*-----------------------------------------------------------------------*/
void __stdargs
printw(char *fmt, ...)
{
va_list ap;
char pbuff[256];
va_start(ap,fmt);
vsprintf(pbuff,fmt,ap);
putstr(pbuff);
}
int __stdargs
scanw(char *fmt, ...)
{
va_list ap;
char pbuf[256];
va_start(ap,fmt);
if (getstr(pbuf) != (char *)EOF)
return sscanf(pbuf, fmt, va_arg(ap,long),va_arg(ap,long),va_arg(ap,long),va_arg(ap,long),va_arg(ap,long));
else return 0;
}
int
getch()
{
int ch;
refresh();
while ( (ch=getevent(ChessWnd)) == -1 )
;
return( ch );
}
char *
getstr(char *buf)
{
int ch;
char *t = buf;
/* last command was load/save */
if (get_file && DoFileRequest(ChessWnd, frhail, buf))
{
get_file = FALSE;
return buf;
}
/* else fall-through, let user type name... */
get_file = FALSE;
refresh();
if (get_command)
EnableWindow();
*buf = '\0'; /* assume nothing first */
while ((ch=getevent(ChessWnd)) != '\r')
switch (ch)
{
case 0x0c: /* ^L i.e. redraw */
strcpy(buf, "bd");
goto finished;
case 0x1c: /* ^\ i.e. EOF */
DisableWindow();
return (char *)EOF;
case '\b': /* backspace, delete */
case 0x7f:
if (t > buf)
{
t--;
printw("\b \b");
refresh();
}
break;
case MOUSE_MOVE:
putstr(movestr);
refresh();
strcpy(buf, movestr);
goto finished;
case MENU_PICK:
strcpy(buf, menuchoice);
goto finished;
case IGNORE_EVENT:
break;
default:
*t++ = ch;
}
*t = '\0';
finished:
DisableWindow();
return (buf);
}
/* clear the screen */
void
clear ()
{
char buf[10];
sprintf(buf,"%c",0x0c);
putstr(buf);
refresh();
}
/* clear to end of line */
void
clrtoeol ()
{
char buf[10];
sprintf(buf,"%c%c",0x9b,0x4b);
putstr(buf);
}
/* move to row, col */
void
move (row, col)
{
char buf[10];
sprintf(buf,"%c%d%c%d%c",0x9b,row+1,0x3b,col+1,0x48);
putstr(buf);
}
/* do a back space */
void
backup ()
{
inst_putch((int)'\b');
}
void
leaveok(void *p, int turnoff)
{
if (turnoff)
cursor_off();
else
cursor_on();
}
void
attron(int what)
{
if (what < 8) /* color change */
setcolors(30+what);
}
void
standout()
{
setcolors(7);
}
void
standend()
{
setcolors(0);
}
void
flash()
{
inst_putch(0x7);
}
extern void dobeep(long);
void beep()
{
dobeep(100);
}
/* unused at moment... */
void crmode(){}
void nocrmode(){}